import {
	BLE_SERVICE,
	BLE_SEARCH_TIMEOUT,
	BLE_CONNECT_TIMEOUT,
	BLE_SEND_TIMEOUT,
	BLE_SERVICE_UUID,
	BLE_SERVER_RX_UUID,
	BLE_SERVER_TX_UUID
} from '~/pages/blueTest/ble.js'
import {
	getBlueToothToken,
	calculateBluetooth
} from '@/api/index.js'
import {
	checkSetting
} from '@/utils/tool.js'
import sha256 from "crypto-js/sha256"
import encUtf8 from "crypto-js/enc-utf8"
import encBase64 from "crypto-js/enc-base64"
import CryptoJS from 'crypto-js'

import { 
	BLE_CMD_CONFIG
} from '~/pages/blueTest/bleConfig.js'





const checkFoundDeviceByImei = (imei, advertisDataFormat) => { // 将查找到的设备与imei进行匹配，判断是否是目标设备
	return imei && imei.indexOf(advertisDataFormat) === 3 && advertisDataFormat.length === 12
}

const ab2hex = (buffer) => {
	const hexArr = Array.prototype.map.call(
		new Uint8Array(buffer),
		function(bit) {
			return ('00' + bit.toString(16)).slice(-2)
		}
	)
	return hexArr.join('')
}

const typedArray = (value) => {
	return new Uint8Array(value.match(/[\da-f]{2}/gi).map(function(h) {
		return parseInt(h, 16)
	}))
}

const imeiToDeviceID = (IMEI) => { // 从imei中截取deviceID
	let deviceId = IMEI.substring(3, 15);
	let str = [];
	for (let i = 6; i >= 1; i--) {
		str.push(`${deviceId.slice((i-1) * 2, (i * 2))}`);
	}
	return str.join(':');
}

const imeiToDeviceIdSource = (IMEI) => { // 从扫描出的设备列表中查找deviceID
	
	const imeiDevice = BLE.deviceList.filter(item => {
		return item.name.indexOf(IMEI)>0
		// checkFoundDeviceByImei(IMEI, item.name)
	})
	if (imeiDevice.length) {
		return imeiDevice[0].deviceId
	}
	console.log(1312312,BLE.deviceList,imeiDevice);
	return ''
}

const toDataArray = (token) => {
	const str = parseInt(token).toString(16)
	const zeroes = '00000000'
	const length = zeroes.length - str.length
	const hexStr = zeroes.substr(0, length) + str
	const array = []
	const step = 2
	for (let i = 0; i < hexStr.length; i += step) {
		array.push(parseInt(hexStr.substring(i, i + step), 16));
	}
	return array;
}

const toPad2HexStr = (num) => {
	return ('0' + (num & 0xFF).toString(16)).slice(-2)
}

const toHexString = (byteArray) => {
	return Array.from(byteArray, function(byte) {
		return toPad2HexStr(byte);
	}).join('')
}
const toHexArray = (byteArray) => {
	return Array.from(byteArray, function(byte) {
		return byte.charCodeAt(0).toString(16);;
	})
}
const toHexArray2 = (byteArray) => {
	return byteArray.match(/.{1,2}/g);
}
const cmdToBuf = (cmd = []) => {
	let buffer = new ArrayBuffer(cmd.length);
	let view = new Uint8Array(buffer);
	for (let i = 0; i < cmd.length; i++) {
	  view[i] = "0x" +cmd[i];
	}
  return buffer;
}
function calculateChecksum(data) {
    let checksum = 0;
    for (let i = 0; i < data.length; i++) {
        checksum ^= "0x" + data[i];  // 异或运算
    }
    return checksum;
}
const getToken = (IMEI) => {
	return new Promise((resolve) => {
		console.log(4564564, BLE.blueToken);
		uni.$emit('blueLog', '获取操作蓝牙的token-->', BLE.blueToken)
		resolve(toDataArray(BLE.blueToken))
 
	})
}
const buildCmd = async (IMEI, cmd, data) => { 
	
	let asciiChar = String.fromCharCode(parseInt(cmd, 16));
	let _cmd=cmd.toString(16) 
	
	let _data=[]
	if(data.length>0)
		_data=toHexArray2(data)
	let _len= toPad2HexStr(_data.length )
	
	let dataArray
	if(data.length==0)
	{
		let xorValue =calculateChecksum([_cmd,'00'])
		dataArray = ['67','74','01',_cmd,'00',toPad2HexStr(xorValue).toString()]
	}
	else
	{
		let _temparray=[_cmd,..._data]
		
		let xorValue =calculateChecksum(_temparray)
		 
		dataArray = ['67','74',_len,_cmd,..._data,toPad2HexStr(xorValue).toString()]
		console.log('发送蓝牙数据dataArray',dataArray);
	} 
	uni.$emit('blueLog', '发送蓝牙数据dataArray-->', dataArray)
	return dataArray
}
// const buildCmd = async (IMEI, cmd, data) => {
// 	let dataArray = [] //await getToken(IMEI);// [0x0A, 0x0A, 0x05, 0x05] //

// 	let index = 0;
// 	let dataLength = typeof data !== 'undefined' ? data.length : 0;
// 	while (index < dataLength) {
// 		dataArray.push(data[index++])
// 	}
// 	dataLength = dataArray.length;
// 	let dataSum = 0;
// 	if (dataLength > 0) {
// 		dataArray.forEach(function(element) {
// 			dataSum += element;
// 		}, this);
// 	}
// 	let crc = toPad2HexStr(cmd + dataSum + dataLength)
// 	let dataStr = toHexString(dataArray);
// 	uni.$emit('blueLog', '发送蓝牙数据dataArray-->', toPad2HexStr(cmd) + toPad2HexStr(dataLength) + dataStr + crc)
// 	return toPad2HexStr(cmd) + toPad2HexStr(dataLength) + dataStr + crc; //"27050a0a0505014b";
// }

const removeFailTaskArrById = (id) => {
	BLE.failTaskArr = BLE.failTaskArr.filter(item => {
		return item.id !== id
	})
}

const BLE = {
	blueToken: '', //蓝牙token
	bluetoothIsConnect: false, // 记录当前蓝牙是否处于连接状态
	deviceList: [], // 存储查询到的设备列表
	deviceListByHistory: [], // 存储历史设备连接列表
	connectTime: null, // 存储查找设备的定时器
	failTaskArr: [], // 记录蓝牙状态由可用变为不可用时需要执行的操作
	init: () => { // 初始化蓝牙模块
		// BLE.deviceList = []
		BLE.failTaskArr = []
		return new Promise(async resolve => {
			const initFailFun = async () => { // 初始化失败后执行
				let bluetoothScope = await checkSetting('scope.bluetooth')
				if (!bluetoothScope) { // 小程序设置未取得微信蓝牙权限
					uni.showModal({
						title: '请先授权蓝牙权限',
						showCancel: false,
						success: (res2) => {
							if (res2.confirm) {
								uni.openSetting()
							}
						}
					})
				} else { // 微信未取得系统蓝牙权限或系统蓝牙未开启
					uni.showModal({
						title: '请确认手机蓝牙是否处于开启状态且已授权微信蓝牙权限',
						showCancel: false
					})
				 
				}
			}
			if (BLE.bluetoothIsConnect) { // 当前处于连接态，直接用
				resolve(true)
			} else {
				await BLE.close()
				uni.openBluetoothAdapter({
					success: (res) => {
						BLE.bluetoothIsConnect = false
						if (res && res.errno === 0) {
							uni.$emit('blueLog', '初始化蓝牙模块 --> 成功', res)
							resolve(true)
							return
						}
						uni.$emit('blueLog', '初始化蓝牙模块 --> 失败', res)
						initFailFun()
						resolve(false)
					},
					fail: (err) => {
						uni.$emit('blueLog', '初始化蓝牙模块 --> 失败', err)
						BLE.bluetoothIsConnect = false
						initFailFun()
						resolve(false)

					}
				})
			}
		})
	},
	connectionHistoryDevice: (historyDevice, timeout) => {
		console.log('连接历史蓝牙设备',historyDevice, imeiToDeviceIdSource(historyDevice.imei));
		uni.$emit('blueLog', '连接历史蓝牙设备', historyDevice, imeiToDeviceIdSource(historyDevice.imei))
		return new Promise(async resolve => {
			const failFun = {
				id: 'connectionHistoryDevice_' + (Math.random() * 1000000000000000).toFixed(0),
				callback: () => {
					resolve()
				}
			}
			BLE.failTaskArr.push(failFun)
			// uni.$emit('blueLog','蓝牙中断推入成功', failFun.id)

			await BLE.disconnect(historyDevice.imei)
			uni.createBLEConnection({
				deviceId: imeiToDeviceIdSource(historyDevice.imei),
				timeout: timeout || BLE_SEARCH_TIMEOUT,
				success: (res) => {
					uni.$emit('blueLog', '连接历史蓝牙设备 --> 成功', res)
					BLE.deviceList = [historyDevice.device]
					resolve(historyDevice.device)
				},
				fail: (err) => {
					if (err && err.errCode === -1) { // 已连接过
						uni.$emit('blueLog', '连接历史蓝牙设备 --> 成功，已连接过就不执行重复连接了')
						BLE.deviceList = [historyDevice.device]
						resolve(historyDevice.device)
						return
					}
					uni.$emit('blueLog', '连接历史蓝牙设备 --> 失败', err, imeiToDeviceIdSource(
						historyDevice.imei))
					resolve()

				},
				complete: () => {
					removeFailTaskArrById(failFun.id)
				},
			})
		})
	},
	search: () => { // 搜寻附近蓝牙设备
		return new Promise(resolve => {
			uni.startBluetoothDevicesDiscovery({
				services: BLE_SERVICE,
				allowDuplicatesKey: false,
				interval: 0,
				//powerLevel:'high',
				success: (res) => {
					if (res && res.errno === 0) {
						uni.$emit('blueLog', '搜寻附近蓝牙设备 --> 成功 ', res)
						resolve(true)
						return
					}
					uni.$emit('blueLog', '搜寻附近蓝牙设备 --> 失败', res)
					resolve(false)

				},
				fail: (err) => {
					uni.$emit('blueLog', '搜寻附近蓝牙设备 --> 失败', err)
					resolve(false)

				},
				complete: () => {}
			})
		})
	},
	stopSearch: () => { // 停止搜寻附近蓝牙设备
		uni.stopBluetoothDevicesDiscovery({
			success: () => {
				uni.$emit('blueLog', '停止搜寻附近的蓝牙外围设备 --> 成功')
			},
			fail: (err) => {
				uni.$emit('blueLog', '停止搜寻附近的蓝牙外围设备 --> 失败', err)
			},
			complete: () => {}
		})
	},
	onSearch: (imei, callback, timeout) => { // 寻找到新设备时的回调 
		BLE.deviceList = []
		clearTimeout(BLE.connectTime)
		let isCallbackExec = false
		const findDeviceCallback = (res) => { // 查找到设备后的回调
			if (res && res.length === 1) {
				const device = res[0]
				uni.$emit('blueLog', '查找设备 -> 成功', device)
				BLE.deviceListByHistory = BLE.deviceListByHistory.filter(item => {
					return item.device.deviceId !== device.deviceId
				})
				const deviceObj = {
					imei,
					device
				}
				BLE.deviceListByHistory.push(deviceObj)
				callback(device)
			} else {
				uni.$emit('blueLog', '查找设备 -> 失败', res)
				callback()
			}
		}
		// 中断推入
		const failFun = {
			id: 'onSearch_' + (Math.random() * 1000000000000000).toFixed(0),
			callback: () => {
				isCallbackExec = true
				clearTimeout(BLE.connectTime)
				BLE.stopSearch()
				findDeviceCallback([])
			}
		}
		BLE.failTaskArr.push(failFun) 

		uni.onBluetoothDeviceFound((res) => {
			uni.$emit('blueLog', '搜索到周边设备', res)
			let devices = res.devices || []
			devices.map(item => {
				item.advertisDataFormat = ab2hex(item.advertisData)
			})
			devices = devices.filter(row => row.name)
			// if (devices?.length > 0)
			// 	uni.$emit('blueLog', '搜索到周边设备(处理后)', devices)
			const imeiDevice = devices.filter(item =>item.name.indexOf(imei)>0)
			if (imeiDevice.length) { // 如果通过imei去连接的设备，则查到到该设备后直接返回即可
				removeFailTaskArrById(failFun.id)
				isCallbackExec = true
				BLE.deviceList = imeiDevice
				BLE.stopSearch()
				findDeviceCallback(imeiDevice)
				return
			}
			BLE.deviceList = [].concat(BLE.deviceList, devices)
		})
		BLE.connectTime = setTimeout(() => {
			clearTimeout(BLE.connectTime)
			if (!isCallbackExec) {
				removeFailTaskArrById(failFun.id)
				BLE.stopSearch()
				findDeviceCallback(BLE.deviceList || [])
			}
		}, timeout || BLE_SEARCH_TIMEOUT)
	},
	onStateChange: () => { // 监听蓝牙适配器状态变化
		uni.onBluetoothAdapterStateChange(res => {
			if (res.available) {
				uni.$emit('blueLog', '[监听]蓝牙适配器可用')
			} else {
				uni.$emit('blueLog', '[监听]蓝牙适配器不可用', BLE.failTaskArr)
				BLE.bluetoothIsConnect = false
				do {
					const failFun = BLE.failTaskArr.shift()
					if (failFun && typeof failFun.callback === 'function') {
						uni.$emit('blueLog', '[蓝牙]执行中断成功', failFun.id)
						failFun.callback()
					}
				} while (BLE.failTaskArr.length)
			}
		})
	},
	onConnectionChange: () => { // 监听蓝牙连接状态变化
		// 假设蓝牙断开
		uni.onBLEConnectionStateChange(res => {
			const {
				connected
			} = res
			if (!connected) {
				uni.$emit('blueLog', '[监听]蓝牙连接状态 --> 已断开')
			} else {
				uni.$emit('blueLog', '[监听]蓝牙连接状态 --> 已连接')
			}
		})
	},
	/*
	getDeviceList: () => { // 获取连接期间已发现的所以蓝牙设备，包括目前和本机处于连接态的设备
	  uni.$emit('blueLog','获取连接期间已发现的所以蓝牙设备，包括目前和本机处于连接态的设备')
	},
	*/
	getState: () => { // 获取本机蓝牙适配器状态
		return new Promise(resolve => {
			uni.getBluetoothAdapterState({
				success: (res) => {
					if (res && res.errno === 0) {
						uni.$emit('blueLog', '获取蓝牙适配器状态 --> 成功', res)
						resolve({
							discovering: res.discovering, // 当前是否正在搜索设备
							available: res.available // 当前蓝牙适配器是否可用
						})
						return
					}
					resolve({
						discovering: '', // 当前是否正在搜索设备
						available: '' // 当前蓝牙适配器是否可用
					})
					uni.$emit('blueLog', '获取蓝牙适配器状态 --> 失败', res)
				},
				fail: (err) => {
					resolve({
						discovering: '', // 当前是否正在搜索设备
						available: '' // 当前蓝牙适配器是否可用
					})
					uni.$emit('blueLog', '获取蓝牙适配器状态 --> 失败', err)
				},
				complete: () => {}
			})
		})
	},
	close: () => { // 关闭本机蓝牙模块
		return new Promise(resolve => {
			uni.closeBluetoothAdapter({
				success: () => {
					uni.$emit('blueLog', '关闭本机蓝牙模块 --> 成功')
					resolve(true)
				},
				fail: (err) => {
					uni.$emit('blueLog', '关闭本机蓝牙模块 --> 失败', err)
					resolve(false)

				},
				complete: () => {}
			})
		})
	},
	disconnect: (imei) => { // 断开蓝牙设备
		return new Promise(resolve => {
			resolve(true)
			/*
			uni.closeBLEConnection({
			  deviceId: imeiToDeviceIdSource(imei), // 设备的 id
			  success: (res) => {
			    uni.$emit('blueLog','断开蓝牙设备 --> 成功', res)
			    BLE.bluetoothIsConnect = false
			    resolve(true)
			  },
			  fail: (err) => {
			    uni.$emit('blueLog','断开蓝牙设备 --> 失败', err)
			    resolve(false)
			  },
			})
			*/
		})
	},
	connect: (imei) => { // 连接蓝牙设备
		return new Promise(async resolve => {
			const failFun = {
				id: 'connect_' + (Math.random() * 1000000000000000).toFixed(0),
				callback: () => {
					resolve(false)
				}
			}
			BLE.failTaskArr.push(failFun)
			// uni.$emit('blueLog','蓝牙中断推入成功', failFun.id)

			await BLE.disconnect(imei)
			uni.$emit('blueLog', '连接蓝牙设备 --> 准备', imei,imeiToDeviceIdSource(imei))
			console.log('连接蓝牙设备 --> 准备', imei,imeiToDeviceIdSource(imei));
			uni.createBLEConnection({
				deviceId: imeiToDeviceIdSource(imei), // 设备的 id
				timeout: BLE_CONNECT_TIMEOUT, // 超时时间，单位ms，不填表示不会超时
				success: (res) => {
					uni.$emit('blueLog', '连接蓝牙设备 --> 成功', res)
					BLE.bluetoothIsConnect = true
					resolve(true)
				},
				fail: (err) => {
					if (err && err.errCode === -1) { // 已连接过
						uni.$emit('blueLog', '连接蓝牙设备 --> 成功，已连接过就不执行重复连接了')
						BLE.bluetoothIsConnect = true
						resolve(true)
						return
					}
					uni.$emit('blueLog', '连接蓝牙设备 --> 失败', err)
					BLE.bluetoothIsConnect = false
					resolve(false)

				},
				complete: () => {
					removeFailTaskArrById(failFun.id)
				}
			})
		})
	},
	getServices: (imei) => {
		return new Promise(resolve => {
			uni.$emit('blueLog', '获取设备所有服务')
			const failFun = {
				id: 'getServices_' + (Math.random() * 1000000000000000).toFixed(0),
				callback: () => {
					resolve()
				}
			}
			BLE.failTaskArr.push(failFun)
			// uni.$emit('blueLog','蓝牙中断推入成功', failFun.id)
			uni.getBLEDeviceServices({
				deviceId: imeiToDeviceIdSource(imei),
				success: (res) => {
					uni.$emit('blueLog', '获取设备所有服务 --> 成功', res)
					resolve(res)
				},
				fail: (err) => {
					uni.$emit('blueLog', '获取设备所有服务 --> 失败', err)
					resolve()
				},
				complete: () => {
					removeFailTaskArrById(failFun.id)
				}
			})
		})
	},
	getCharacteristicId: (imei, serviceId) => {
		return new Promise(resolve => {
			uni.$emit('blueLog', '获取设备所有特征值')
			const failFun = {
				id: 'getCharacteristicId_' + (Math.random() * 1000000000000000).toFixed(0),
				callback: () => {
					resolve()
				}
			}
			BLE.failTaskArr.push(failFun)
			// uni.$emit('blueLog','蓝牙中断推入成功', failFun.id)
			uni.getBLEDeviceCharacteristics({
				deviceId: imeiToDeviceIdSource(imei),
				serviceId: serviceId,
				success: (res) => {
					uni.$emit('blueLog', '获取某个服务所有特征值 --> 成功', res)
					resolve()
				},
				fail: (err) => {
					uni.$emit('blueLog', '获取某个服务所有特征值 --> 失败', err)
					resolve()
				},
				complete: () => {
					removeFailTaskArrById(failFun.id)
				}
			})
		})
	},
	openNotice: (imei, serviceId, characteristicId) => {
		console.log('openNotice',imeiToDeviceIdSource(imei),serviceId,characteristicId);
		uni.notifyBLECharacteristicValueChange({
			deviceId: imeiToDeviceIdSource(imei),
			serviceId: serviceId,
			characteristicId: characteristicId,
			state: true, // 是否启用 notify
			success: (res) => {
				uni.$emit('blueLog', '开启蓝牙监听 --> 成功', res)
			},
			fail: (err) => {
				uni.$emit('blueLog', '开启蓝牙监听 --> 失败', err)
			}
		})
	},
	onListen: (imei, serviceId, characteristicId, callback) => {
		uni.onBLECharacteristicValueChange((res) => { 
			callback && callback(res)
		})
	},
	sendAuthor:  (imei,first=true,data='') => {
		return new Promise(async(resolve) => {
 
			let sendOnListen = false
			let sendOnListenTime

			// const buffer = typedArray(await buildCmd(imei, BLE_CMD_CONFIG.AUTHOR, '9999988888forBSR')).buffer
			//const buffer =  cmdToBuf(await buildCmd(imei, BLE_CMD_CONFIG.AUTHOR, '9999988888forBSR'))
			let buffer
			if(first)
				buffer= cmdToBuf(await buildCmd(imei, BLE_CMD_CONFIG.AUTHOR, []))//cmdToBuf(['67','74','01','8A','00','8A'])
			else
				buffer=  cmdToBuf(await buildCmd(imei, BLE_CMD_CONFIG.AUTHOR, data))
			
			
			// 接收蓝牙数据
			BLE.onListen(imei, BLE_SERVICE_UUID, BLE_SERVER_TX_UUID, (res) => {
				// if (sendOnListen) { // 说明已经执行了超时逻辑
				// 	return
				// }
				sendOnListen = true
				res.valueFormat = ab2hex(res.value)
				uni.$emit('blueLog', '蓝牙设备接收验证数据 --> 成功', res)
				resolve(res)
			})
			
			uni.writeBLECharacteristicValue({
				deviceId: imeiToDeviceIdSource(imei), // 蓝牙设备 id 根据imei截取得到
				serviceId: BLE_SERVICE_UUID, // 蓝牙特征值对应服务的 uuid
				characteristicId: BLE_SERVER_RX_UUID, // 蓝牙特征值的 uuid
				value: buffer, // 蓝牙设备特征值对应的二进制值
				writeType:'write',//强制回复写，不支持时报错
				success: (res) => {
					
					uni.$emit('blueLog', '向蓝牙设备发送验证数据 --> 成功', res)
					clearTimeout(sendOnListenTime)
					sendOnListenTime = setTimeout(() => {
						clearTimeout(sendOnListenTime)
						if (!sendOnListen) {
							uni.$emit('blueLog', '接收蓝牙验证数据 --> 超时')
							sendOnListen = true
							resolve(false)
						}
					}, BLE_SEND_TIMEOUT)
				},
				fail: (err) => {
					uni.$emit('blueLog', '向蓝牙设备发送验证数据 --> 失败', err)
					resolve(false)
				}
			})
		})
	},
	send: async (imei, value, data, success, fail, complete) => { // 向蓝牙设备发送指令
		let sendOnListen = false
		let sendOnListenTime

		const isConnect = await BLE.connect(imei)
		if (isConnect) { // 连接成功
			uni.$emit('blueLog', '蓝牙连接成功')
			const serviceId = await BLE.getServices(imei)
			const characteristicId = await BLE.getCharacteristicId(imei, BLE_SERVICE_UUID)
			  
			// 开启监听通知
			BLE.openNotice(imei, BLE_SERVICE_UUID, BLE_SERVER_TX_UUID)
			
			let _re=await BLE.sendAuthor(imei) 
			if(!_re)
			{
				fail()
				return
			}
			else
			{
				uni.$emit('blueLog', '第一次蓝牙验证 --> 成功', _re)
				console.log('第一次蓝牙验证', _re);
				let _mac=_re.valueFormat.substring(10,22)
				let _encryption=_re.valueFormat.substring(22,30)
				
				let _encryptedRes=await calculateBluetooth({
				  "deviceNo": "string",
				  "keyMaterial": _mac+_encryption
				})
				console.log('encrypted',_encryptedRes);
				
				//（6字节MAC+4字节秘钥因子+6字节0x00）加密
				let _encrypted=_encryptedRes.data.key
				  
				uni.$emit('blueLog', 'mac和加密因子', _mac+'|'+_encryption)
				
				console.log('mac和加密因子',  _mac+'   '+_encryption);
				//let characteristicIdse = await BLE.getCharacteristicId(imei, BLE_SERVICE_UUID)
				 
				 let _secondere=await BLE.sendAuthor(imei,false,_encrypted)
				 if(!_secondere)
				 {
				 	fail()
				  	return
				 }
				 else
				 {
				  	uni.$emit('blueLog', '第二次蓝牙验证 --> 成功', _secondere)
					//发送指令
					let buffer= cmdToBuf(await buildCmd(imei, value, []))
					
					//uni.$emit('blueLog', '发送蓝牙数据_sendmsg-->',await buildCmd(imei, value, data))
					const failFun = {
						id: 'send_' + (Math.random() * 1000000000000000).toFixed(0),
						callback: () => {
							fail()
						}
					}
					BLE.failTaskArr.push(failFun) 
					
					// 接收蓝牙数据
					BLE.onListen(imei, BLE_SERVICE_UUID, BLE_SERVER_TX_UUID, (res) => {
						if (sendOnListen) { // 说明已经执行了超时逻辑
							return
						}
						sendOnListen = true
						res.valueFormat = ab2hex(res.value)
						success && success(res)
					})
					
					uni.writeBLECharacteristicValue({
						deviceId: imeiToDeviceIdSource(imei), // 蓝牙设备 id 根据imei截取得到
						serviceId: BLE_SERVICE_UUID, // 蓝牙特征值对应服务的 uuid
						characteristicId: BLE_SERVER_RX_UUID, // 蓝牙特征值的 uuid
						value: buffer, // 蓝牙设备特征值对应的二进制值
						writeType:'write',//强制回复写，不支持时报错
						success: (res) => {
							uni.$emit('blueLog', '向蓝牙设备发送数据 --> 成功', res)
							clearTimeout(sendOnListenTime)
							sendOnListenTime = setTimeout(() => {
								clearTimeout(sendOnListenTime)
								if (!sendOnListen) {
									uni.$emit('blueLog', '接收蓝牙数据 --> 超时')
									sendOnListen = true
									fail()
					
								}
							}, BLE_SEND_TIMEOUT)
						},
						fail: (err) => {
							uni.$emit('blueLog', '向蓝牙设备发送数据 --> 失败', err)
							fail && fail(err)
					
						},
						complete: () => {
							removeFailTaskArrById(failFun.id)
							complete && complete()
						}
					})
					
				 }
			 
			}
			

			// // 接收蓝牙数据
			// BLE.onListen(imei, BLE_SERVICE_UUID, BLE_SERVER_TX_UUID, (res) => {
			// 	if (sendOnListen) { // 说明已经执行了超时逻辑
			// 		return
			// 	}
			// 	sendOnListen = true
			// 	res.valueFormat = ab2hex(res.value)
			// 	success && success(res)
			// })
			// // 开启监听通知
			// BLE.openNotice(imei, BLE_SERVICE_UUID, BLE_SERVER_TX_UUID)
			// // 发送蓝牙数据
		 

			// const buffer = typedArray(await buildCmd(imei, value, data)).buffer
			// //uni.$emit('blueLog', '发送蓝牙数据_sendmsg-->',await buildCmd(imei, value, data))
			// const failFun = {
			// 	id: 'send_' + (Math.random() * 1000000000000000).toFixed(0),
			// 	callback: () => {
			// 		fail()
			// 	}
			// }
			// BLE.failTaskArr.push(failFun)
			// // uni.$emit('blueLog','蓝牙中断推入成功', failFun.id)

			// uni.writeBLECharacteristicValue({
			// 	deviceId: imeiToDeviceIdSource(imei), // 蓝牙设备 id 根据imei截取得到
			// 	serviceId: BLE_SERVICE_UUID, // 蓝牙特征值对应服务的 uuid
			// 	characteristicId: BLE_SERVER_RX_UUID, // 蓝牙特征值的 uuid
			// 	value: buffer, // 蓝牙设备特征值对应的二进制值
			// 	success: (res) => {
			// 		uni.$emit('blueLog', '向蓝牙设备发送数据 --> 成功', res)
			// 		clearTimeout(sendOnListenTime)
			// 		sendOnListenTime = setTimeout(() => {
			// 			clearTimeout(sendOnListenTime)
			// 			if (!sendOnListen) {
			// 				uni.$emit('blueLog', '接收蓝牙数据 --> 超时')
			// 				sendOnListen = true
			// 				fail()

			// 			}
			// 		}, BLE_SEND_TIMEOUT)
			// 	},
			// 	fail: (err) => {
			// 		uni.$emit('blueLog', '向蓝牙设备发送数据 --> 失败', err)
			// 		fail && fail(err)

			// 	},
			// 	complete: () => {
			// 		removeFailTaskArrById(failFun.id)
			// 		complete && complete()
			// 	}
			// })
		} else { // 未连接
			uni.showModal({
				title: '蓝牙连接失败，请重试',
				showCancel: false
			})
			fail && fail()

		}
	}
}

BLE.onStateChange() // 启用蓝牙状态变化监听
// BLE.onConnectionChange() // 启用蓝牙连接状态变化监听

/**
 * @description 处理接口请求参数拼接，即返回携带签名后的参数。普通接口请求以及文件上传均需要调用此函数
 * @param params 请求参数
 * @param url 请求接口地址，非必填
 * @returns {{data: {traceId: string, tenantId: number, platform: string}, header: {_s: *, _t: number, 'Content-Type': string}}}
 */
function generateAjaxParams(params = {}, url = '') {
	const timestamp = new Date().valueOf()
	const platformConfig = {
		tenantId: "2", // 租户ID
		secret: 'yp1j501g0rc2v156t8bmja0q4gqz5ykfae9bq70unhxe5s1y16c97otwawx3wwzw', // 用作Authorization生成
		sign: 'a3sw1aw4ij0zyueqd81l1zv4iryw4kcd8jy3uufs7csqo1trkr6zbuj6e32qx7mg', // 用作参数签名
		deviceId: 'deviceId_' + '17313105266271532281036',
		token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwaW4iOiJhXzM5ZWRmYTkwMDQwMGNkYSIsInVzZXJfbmFtZSI6ImFfMzllZGZhOTAwNDAwY2RhIiwib3BlbmlkIjoibzJTX3M2OVIydkt5U2dKNWRDZHF0Ql9TZi1mNCIsInNjb3BlIjpbImFsbCJdLCJuaWNrbmFtZSI6IuWQtOWkj-WzsCIsImF2YXRhciI6Imh0dHBzOi8vbHVvcGluZy11cGxvYWQub3NzLWNuLXNoYW5naGFpLmFsaXl1bmNzLmNvbS9kb3dubG9hZC9iYWNrZW5kLzIvdHlwZS8yMDI0MTEwOC9hMDBhMmY2Ni1jYWZjLTRiZTEtYmZlMy1hM2YzOGViYWFhOWMucG5nIiwiZXhwIjoxNzM0MDUwOTM0LCJkZXZpY2VJZCI6ImRldmljZUlkXzE3MzEzMTA1MjY2MjcxNTMyMjgxMDM2IiwiYXV0aG9yaXRpZXMiOlsiTk9STUFMIl0sImp0aSI6IjJlNmQ2ZWM5LWEyMDYtNDk0NC04YjU5LWRhOGQ4MGE1NjkwMSIsInBsYXRmb3JtIjoid2VjaGF0IiwiY2xpZW50X2lkIjoiMiJ9.eqdHV_1CRPQ5FWv4YQjNJbY8-gCGZeS-t10_c78geJE'
	}
	const publicParams = {
		// 全局请求公共参数
		platform: 'wechat',
		traceId: timestamp + (Math.random() * 100000000000).toFixed(0),
		deviceId: platformConfig.deviceId,
		tenantId: platformConfig.tenantId,

	}
	const _data = Object.assign(publicParams, params)
	const publicHeaders = {
		// 全局请求公共头
		_t: timestamp,
		_s: sha256(JSON.stringify(_data) + `_t=${timestamp}${platformConfig.sign}`).toString(), // 当前请求参数的签名
		'Content-Type': 'application/json',
		'accept-language': 'zh-CN', // 语言设置
		domain: 'ebikecmsdev.bsrnykj.com',
		Host: 'ebikecmsdev.bsrnykj.com',
		appId: 'wx5cf6c2331a3cfc5e'
	}

	const wordArr = encUtf8.parse(platformConfig.tenantId + ':' + platformConfig.secret)
	const base64 = encBase64.stringify(wordArr)
	publicHeaders['Authorization'] = 'Basic ' + base64
	//publicHeaders['Authorization'] = 'Bearer ' + platformConfig.token

	return {
		data: _data,
		header: publicHeaders
	}
}
export default BLE